home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr05
/
xnot12a.zip
/
KBD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-20
|
10KB
|
452 lines
#include "jam.h"
#include "stdlib.h"
/*
* Terminal independent keyboard handling.
*/
#include "def.h"
#include "kbd.h"
#define EXTERN
#include "key.h"
#include "macro.h"
#ifndef METABIT
# define METABIT 0x80
#endif
#ifdef BSMAP
static int bs_map = BSMAP;
/*
* Toggle backspace mapping
*/
bsmap(f, n)
int f, n;
{
if(f & FFARG) bs_map = n > 0;
else bs_map = ! bs_map;
ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
return TRUE;
}
#endif
#ifndef NO_DPROMPT
#define PROMPTL 80
char prompt[PROMPTL], *promptp;
#endif
static int pushed = FALSE;
static int pushedc;
VOID ungetkey(c)
int c;
{
if(pushed && c==CCHR('['))
pushedc |= METABIT;
else
pushedc = c;
pushed = TRUE;
}
int getkey(flag)
int flag;
{
int c;
#ifndef NO_DPROMPT
if(flag && !pushed) {
if(prompt[0]!='\0' && ttwait()) {
ewprintf("%s", prompt); /* avoid problems with % */
update(); /* put the cursor back */
epresf = KPROMPT;
}
if(promptp > prompt)
*(promptp-1) = ' ';
}
#endif
if(pushed) {
c = pushedc;
pushed = FALSE;
}
else
c = getkbd();
#ifdef BSMAP
if(bs_map)
if(c==CCHR('H'))
c=CCHR('?');
else if(c==CCHR('?'))
c=CCHR('H');
#endif
if(c & METABIT) {
pushedc = c & ~METABIT;
pushed = TRUE;
c = CCHR('[');
}
#ifndef NO_DPROMPT
if(flag && promptp < &prompt[PROMPTL - 5]) {
promptp = mykeyname(promptp, c);
*promptp++ = '-';
*promptp = '\0';
}
#endif
return c;
}
/*
* doscan scans a keymap for a keyboard character and returns a pointer
* to the function associated with that character. Sets ele to the
* keymap element the keyboard was found in as a side effect.
*/
MAP_ELEMENT *ele;
PF doscan(map, c)
register KEYMAP *map;
register int c;
{
/* local register copy for faster access
*/
register MAP_ELEMENT *elec = &map->map_element[0];
register MAP_ELEMENT *last = &map->map_element[map->map_num];
#ifndef WINDOWED /* major hack since kbd table out of whack */
if (c == KEXTEND)
return (silent_extend);
#endif
while(elec < last && c > elec->k_num)
elec++;
ele = elec; /* used by prefix and binding code */
if(elec >= last || c < elec->k_base)
return map->map_default;
return elec->k_funcp[c - elec->k_base];
}
doin()
{
KEYMAP *curmap;
PF funct;
#ifndef NO_DPROMPT
*(promptp = prompt) = '\0';
#endif
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
key.k_count = 0;
while((funct=doscan(curmap,(key.k_chars[key.k_count++]=getkey(TRUE))))
== prefix)
curmap = ele->k_prefmap;
if(macrodef && macrocount < MAXMACRO)
if(funct != (PF)silent_extend)
macro[macrocount++].m_funct = funct;
return (*funct)(0, 1);
}
rescan(f, n)
int f, n;
{
int c;
register KEYMAP *curmap;
int i;
PF fp;
int mode = curbp->b_nmodes;
for(;;) {
if(ISUPPER(key.k_chars[key.k_count-1])) {
c = TOLOWER(key.k_chars[key.k_count-1]);
curmap = curbp->b_modes[mode]->p_map;
for(i=0; i < key.k_count-1; i++) {
if((fp=doscan(curmap,(key.k_chars[i]))) != prefix)
break;
curmap = ele->k_prefmap;
}
if(fp==prefix) {
if((fp = doscan(curmap, c)) == prefix)
while((fp=doscan(curmap,key.k_chars[key.k_count++] =
getkey(TRUE))) == prefix)
curmap = ele->k_prefmap;
if(fp!=rescan) {
#ifndef NO_MACRO
if(macrodef && macrocount <= MAXMACRO)
if(fp != (PF)silent_extend)
macro[macrocount-1].m_funct = fp;
#endif
return (*fp)(f, n);
}
}
}
/* try previous mode */
if(--mode < 0)
{
/* Using extended commands fouls up
* the world because cntrl-x 'unknown' recovers
* by dumping chars to input stream. Ughlest for mouse,
* refresh, resize, so this hack restarts the aborted/interupting
* command...
*/
KCHAR kc = key.k_chars[key.k_count-1];
key.k_count = 0;
ttflushinput(FALSE);
if (kc == KEXTEND)
AddKchar(KEXTEND);
return ABORT;
}
curmap = curbp->b_modes[mode]->p_map;
for(i=0; i < key.k_count; i++) {
if((fp=doscan(curmap,(key.k_chars[i]))) != prefix)
break;
curmap = ele->k_prefmap;
}
if(fp==prefix) {
while((fp=doscan(curmap,key.k_chars[i++]=getkey(TRUE)))
== prefix)
curmap = ele->k_prefmap;
key.k_count = i;
}
if(fp!=rescan && i>=key.k_count-1) {
#ifndef NO_MACRO
if(macrodef && macrocount <= MAXMACRO)
if(fp != (PF)silent_extend)
macro[macrocount-1].m_funct = fp;
#endif
return (*fp)(f, n);
}
}
}
universal_argument(f, n)
int f, n;
{
int c, nn=4;
KEYMAP *curmap;
PF funct;
if(f&FFUNIV) nn *= n;
for(;;) {
key.k_chars[0] = c = getkey(TRUE);
key.k_count = 1;
if(c == '-')
return negative_argument(f, nn);
if(c >= '0' && c <= '9')
return digit_argument(f, nn);
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
while((funct=doscan(curmap,c)) == prefix) {
curmap = ele->k_prefmap;
key.k_chars[key.k_count++] = c = getkey(TRUE);
}
if(funct != universal_argument) {
#ifndef NO_MACRO
if(macrodef && macrocount < MAXMACRO-1) {
if(f&FFARG) macrocount--;
macro[macrocount++].m_count = nn;
macro[macrocount++].m_funct = funct;
}
#endif
return (*funct)(FFUNIV, nn);
}
nn <<= 2;
}
}
/*ARGSUSED*/
digit_argument(f, n)
int f, n;
{
int nn, c;
KEYMAP *curmap;
PF funct;
nn = key.k_chars[key.k_count-1] - '0';
for(;;) {
c = getkey(TRUE);
if(c < '0' || c > '9') break;
nn *= 10;
nn += c - '0';
}
key.k_chars[0] = c;
key.k_count = 1;
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
while((funct=doscan(curmap,c)) == prefix) {
curmap = ele->k_prefmap;
key.k_chars[key.k_count++] = c = getkey(TRUE);
}
#ifndef NO_MACRO
if(macrodef && macrocount < MAXMACRO-1)
{
if(f&FFARG)
macrocount--;
else
macro[macrocount-1].m_funct = universal_argument;
macro[macrocount++].m_count = nn;
macro[macrocount++].m_funct = funct;
}
#endif
return (*funct)(FFOTHARG, nn);
}
negative_argument(f, n)
int f, n;
{
int nn = 0, c;
KEYMAP *curmap;
PF funct;
for(;;) {
c = getkey(TRUE);
if(c < '0' || c > '9') break;
nn *= 10;
nn += c - '0';
}
if(nn)
nn = -nn;
else
nn = -n;
key.k_chars[0] = c;
key.k_count = 1;
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
while((funct=doscan(curmap,c)) == prefix) {
curmap = ele->k_prefmap;
key.k_chars[key.k_count++] = c = getkey(TRUE);
}
#ifndef NO_MACRO
if(macrodef && macrocount < MAXMACRO-1)
{
if(f&FFARG)
macrocount--;
else
macro[macrocount-1].m_funct = universal_argument;
macro[macrocount++].m_count = nn;
macro[macrocount++].m_funct = funct;
}
#endif
return (*funct)(FFNEGARG, nn);
}
/*
* Insert a character. While defining a macro, create a "LINE" containing
* all inserted characters.
*/
selfinsert(f, n)
int f, n;
{
register int c;
int count;
#ifndef NO_MACRO
LINE *lp;
#endif
if (curbp->b_flag & BFVIEW)
{
ttbeep();
return FALSE;
}
if (filetimechanged(curbp))
return(FALSE);
clearUndo(curbp);
if ((curbp->b_flag & BFOVERWRITE) == 0)
cacheInsert((RSIZE)n); /* no undo for overwrite (yet) */
if (n < 0)
return FALSE;
if (n == 0)
return TRUE;
c = key.k_chars[key.k_count-1];
if(macrodef && macrocount < MAXMACRO) {
if(f & FFARG)
macrocount -= 2;
if(lastflag & CFINS) { /* last command was insert -- tack on end */
macrocount--;
if(maclcur->l_size < maclcur->l_used + n) {
if((lp = lallocx(maclcur->l_used + n)) == NULL)
return FALSE;
lp->l_fp = maclcur->l_fp;
lp->l_bp = maclcur->l_bp;
lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
bcopy(maclcur->l_text, lp->l_text, (size_t)maclcur->l_used);
for(count = maclcur->l_used; count < lp->l_used; count++)
lp->l_text[count] = (char)c;
free((char *)maclcur);
maclcur = lp;
} else {
maclcur->l_used += n;
for(count = maclcur->l_used-n; count < maclcur->l_used; count++)
maclcur->l_text[count] = (char)c;
}
} else {
macro[macrocount-1].m_funct = insert;
if((lp = lallocx(n)) == NULL)
return FALSE;
lp->l_bp = maclcur;
lp->l_fp = maclcur->l_fp;
maclcur->l_fp = lp;
maclcur = lp;
for(count = 0; count < n; count++)
lp->l_text[count] = (char)c;
}
thisflag |= CFINS;
}
/* do work
*/
if(c == '\n') {
do {
count = lnewline();
} while (--n && count==TRUE);
return count;
}
if(curbp->b_flag & BFOVERWRITE) { /* Overwrite mode */
lchange(WFEDIT);
changelineflag(curwp->w_dotp, TRUE);
while(curwp->w_doto < llength(curwp->w_dotp) && n--)
lputc(curwp->w_dotp, curwp->w_doto++, (char)c);
if(n<=0)
return TRUE;
}
{
int s = linsert(n, c);
/* special case major hack for autoindent
*/
#if 0
if (s)
{
if ((n == 1) && (c == '}'))
alignindent(0, 1);
}
#endif
return(s);
}
}
/*
* this could be implemented as a keymap with everthing defined
* as self-insert.
*/
quote(f, n)
int f, n;
{
register int c;
key.k_count = 1;
if((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
key.k_chars[0] -= (int)'0';
if((c = getkey(TRUE)) >= (int)'0' && c <= (int)'7') {
key.k_chars[0] <<= 3;
key.k_chars[0] += c - (int)'0';
if((c = getkey(TRUE)) >= (int)'0' && c <= (int)'7') {
key.k_chars[0] <<= 3;
key.k_chars[0] += c - (int)'0';
} else ungetkey(c);
} else ungetkey(c);
}
return selfinsert(f, n);
}